package com.hhf.ds.service;

import com.alibaba.druid.pool.DruidDataSource;
import com.hhf.ds.entity.PageBean;
import com.hhf.ds.util.CoreAssert;
import com.hhf.ds.util.ExportUtils;
import com.hhf.ds.util.SqlParser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author haohaifeng
 * @date 2021/1/22 11:34
 */
@Slf4j
@Component
public class ListExpSupport {
    @Autowired
    private PageSupport pageSupport;
    @Autowired
    private RptService rptService;

    private static Map<String,String> rptSqlCache = new ConcurrentHashMap<>();

    public void exp(HttpServletResponse response, Map<String, Object> queryArgs) throws IOException, SQLException {
        String rptCode = String.valueOf(queryArgs.get("rptCode"));
        CoreAssert.notBlank(rptCode, "rptCode为空");
        ByteArrayInputStream bis = rptService.getRptExprStream(rptCode);
        SqlParser sqlParser = new SqlParser(rptCode, bis);
        String fileName = sqlParser.getRptName();
        if (StringUtils.isBlank(fileName)) {
            fileName = String.valueOf(System.nanoTime());
        }
        String sql = sqlParser.parseSQL(queryArgs);
        rptSqlCache.put(rptCode, sql);
        String[] titleCols = sqlParser.getTitleCols();
        List<Map<String, String>> list = null;
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            connection = rptService.getConnByRptCode(rptCode);
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sql);
            list = convertList(resultSet);
        } catch (SQLException e) {
            log.error(e.getMessage(), e);
        } finally {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
        ExportUtils.exportExcel(response,fileName,list,titleCols);
    }
    public PageBean pageList(Map<String, Object> queryArgs) {
        String rptCode = String.valueOf(queryArgs.get("rptCode"));
        CoreAssert.notBlank(rptCode, "rptCode为空");
        Object pageSizeObj = queryArgs.get("pageSize");
        Object pageNoObj = queryArgs.get("pageNo");
        PageBean pageResult = null;
        ByteArrayInputStream bis = rptService.getRptExprStream(rptCode);
        SqlParser sqlParser = new SqlParser(rptCode, bis);
        String sql = sqlParser.parseSQL(queryArgs);
        rptSqlCache.put(rptCode, sql);
        DruidDataSource dataSource = rptService.getDataSourceByRptCode(rptCode);
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        // 如果不分页全量查询
        if (pageSizeObj == null || StringUtils.isBlank(pageSizeObj.toString())
                || pageNoObj == null || StringUtils.isBlank(pageNoObj.toString())) {
            pageResult = new PageBean();

            List<Map<String, Object>> maps = jdbcTemplate.query(sql, new ColumnMapRowMapper() {
                @Override
                protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
                    return rs.getString(index);
                }
            });
            pageResult.setList(maps);
            pageResult.setTotal(maps.size());
        } else {
            // 如果分页查询
            Integer pageSize = Integer.parseInt(pageSizeObj.toString());
            Integer pageNum = Integer.parseInt(pageNoObj.toString());
            PageBean pageBean = new PageBean();
            pageBean.setPageSize(pageSize);
            pageBean.setPageNo(pageNum);
            pageResult = pageSupport.queryByPage(jdbcTemplate, sql, pageBean);
        }
        return pageResult;
    }

    private List<Map<String, String>> convertList(ResultSet rs) throws SQLException {
        List<Map<String, String>> list = new ArrayList();
        ResultSetMetaData md = rs.getMetaData();
        int columnCount = md.getColumnCount();
        while (rs.next()) {
            Map<String, String> rowData = new LinkedHashMap();
            for (int i = 1; i <= columnCount; i++) {
                rowData.put(md.getColumnName(i), rs.getString(i));
            }
            list.add(rowData);
        }
        return list;
    }

    public String getExecSql(String rptCode) {
        String result = rptSqlCache.get(rptCode);
        return result == null ? "" : result;
    }
}
